import React from 'react';
import Picker from 'rmc-picker';
import { CSSTransitionGroup } from 'react-transition-group';
import cx from 'classnames';
import s from './index.m.less';

// 当前仅支持,年,月,日,时,分
const AllColums = ['year', 'month', 'day', 'hour', 'min'];
const addZero = num => (num < 10 ? `0${num}` : num);

/**
 * in 可能是字符串日期，也可能是秒时间戳,也可能是undefind
 * 返回 Date对象
 */
const convertDate = input => {
    let num = input;
    if (typeof input === 'string') {
        num = WPT.Util.getStamp(input);
    } else if (!input) {
        return 0;
    }
    return new Date(num * 1000);
};
export default class DateInner extends React.Component {
    static defaultProps = {
        title: '',
        onChange: () => {},
        onCancel: () => {},
        cancelName: '取消',
        confirmName: '确定',
        confirmClass: null,
        value: 0, // string | stamp,如果是日期时使用时间戳】
        beginTime: null, // 开始时间，秒时间戳s
        endTime: null, // 结束时间，秒时间戳s
    };

    constructor(p) {
        super(p);
        this.reset(this.props);
    }

    componentWillReceiveProps(np) {
        if (np.value != this.props.value || np.uuid != this.props.uuid) {
            this.reset(np, 1);
        }
    }

    // 日期仓库
    DateBase = {
        limitDateStart: null,
        limitDateEnd: null,
        year: { title: '年', start: new Date().getFullYear(), end: new Date().getFullYear() + 4 },
        month: { title: '月', start: 1, end: 12 },
        day: { title: '日', start: 1, end: 31 },
        hour: { title: '时', start: 0, end: 23 },
        min: { title: '分', start: 0, end: 59 },
        init(limitStart, limitEnd, defValue, callBack) {
            // 初始化年，开始区间
            const dateStart = convertDate(limitStart);
            this.limitDateStart = dateStart;
            if (dateStart) {
                this.limitDateStart = dateStart;
                this.year.start = dateStart.getFullYear();

                // 设置end
                if (!limitEnd) {
                    this.year.end = this.year.start + 4;
                }
            }

            // 初始化年，结束区间
            const dateEnd = convertDate(limitEnd);
            this.limitDateEnd = dateEnd;
            if (dateEnd) {
                this.year.end = dateEnd.getFullYear();

                // 设置start
                if (!limitStart) {
                    this.year.start = this.year.end - 4;
                }
            }

            if (dateStart && dateEnd && dateEnd.getTime() <= dateStart.getTime()) {
                const info = `【${WPT.Util.formatDate('Y/m/d H:i:s', dateStart)} - ${WPT.Util.formatDate(
                    'Y/m/d H:i:s',
                    dateEnd
                )}】`;
                throw new Error(`时间开始区间，必须大于结束区间！${info}`);
            }

            // 仪表盘默认时间为开始年份第一天，上午8点
            const d = convertDate(defValue) || new Date(this.year.start, 1, 1, 8, 0);
            const arg = {
                year: d.getFullYear(),
                month: d.getMonth() + 1,
                day: d.getDate(),
                hour: d.getHours(),
                min: d.getMinutes(),
            };
            this.reInit(arg);
            callBack(arg);
        },
        reInit({
            year, month, day, hour
        }) {
            // 初始化月，日，时，分
            const setData = (date, key, defMonth, defDay, defHour, defMin) => {
                // 默认值
                this.month[key] = defMonth;
                this.day[key] = defDay;
                this.hour[key] = defHour;
                this.min[key] = defMin;
                if (!date) return;

                // 极限值默认值
                const _month = date.getMonth() + 1;
                const _day = date.getDate();
                const _hour = date.getHours();

                // 匹配极限值，如果选择的年year是开始年
                if (year == date.getFullYear()) {
                    this.month[key] = _month;
                    if (month === _month) {
                        // 同年，同月
                        this.day[key] = _day;
                        if (day === _day) {
                            // 同年，同月,同日
                            this.hour[key] = _hour;
                            if (hour === _hour) {
                                // 同年，同月,同日，同时
                                this.min[key] = date.getMinutes();
                            }
                        }
                    }
                }
            };
            const inputDate = new Date(year, month, 0);
            setData(this.limitDateStart, 'start', 1, 1, 0, 0);
            setData(this.limitDateEnd, 'end', 12, inputDate.getDate(), 23, 59);
        },
    };

    /**
     * 用于在组件外部重设状态
     */
    reset = (props, isUpdata) => {
        const {
            beginTime, endTime, value, datas
        } = props;

        // 通用数据，不需要设置日期
        if (datas) return;

        // 设置年月日时分，最多三个
        const colums = [];
        AllColums.forEach(it => props[it] && colums.push(it));
        colums.length = colums.length > 3 ? 3 : colums.length;

        this.DateBase.init(beginTime, endTime, value, chooseState => {
            const state = {
                ...chooseState,
                colums,
                common: value, // 通用数据
            };
            if (isUpdata) this.setState(state);
            else this.state = state;
        });
    };

    // 处理单列日期选择
    handleTimeChange = unit => value => {
        this.state[unit] = value;
        const {
            year, month, day, hour, min
        } = this.state;
        this.props.onChange(parseInt(new Date(year, month - 1, day, hour, min).getTime() / 1000));
    };

    // 处理通用单列数据选择
    handleCommonChange = value => {
        this.props.onChange(value);
    };

    submit = () => {
        this.props.onOk();
        this.props.close();
    };

    cancel = () => this.props.onCancel();

    // 能用数据选择器数据及dom
    renderCommonUI = () => {
        const { datas, value } = this.props;
        return (
            <div className={s.colum}>
                <Picker selectedValue={value} onValueChange={this.handleCommonChange} defaultSelectedValue={value}>
                    {datas.map((it, i) => {
                        let name;
                        // 兼容对象类型数据和字符串类型数据
                        if (typeof it === 'object') {
                            name = it.name;
                        } else if (typeof it === 'string') {
                            name = it;
                        }
                        name = name || 'invalid';

                        return (
                            <Picker.Item value={it} key={i}>
                                <div>{name}</div>
                            </Picker.Item>
                        );
                    })}
                </Picker>
            </div>
        );
    };

    // 日期选择器数据及dom
    renderDateUI = () => {
        const {
            state,
            state: { colums, year, month },
        } = this;
        return colums.map(type => {
            const { title, start, end } = this.DateBase[type];
            const items = [];

            // 只有一个“年”与只有一个'月'，与有三列时，样式不同
            let itemStyle = { width: '80%' };
            if (colums.length === 1) {
                type === 'year' ? (itemStyle = {}) : (itemStyle.width = '96%');
            }

            // 判断今天
            const now = new Date();
            let today = false;
            if (
                (!colums.includes('year') || now.getFullYear() === year)
                && (!colums.includes('month') || now.getMonth() + 1 === month)
            ) {
                today = now.getDate();
            }

            for (let val = start; val <= end; val++) {
                items.push(
                    <Picker.Item value={val} key={val}>
                        <div style={itemStyle}>{today === val ? '今' : addZero(val)}</div>
                    </Picker.Item>
                );
            }

            return (
                <div className={s.colum} key={type}>
                    <div className={cx(s.unit, { [s.year]: type === 'year' })}>{title}</div>
                    <Picker
                        type="stanley"
                        selectedValue={state[type]}
                        onValueChange={this.handleTimeChange(type)}
                        defaultSelectedValue={state[type]}
                    >
                        {items}
                    </Picker>
                </div>
            );
        });
    };

    render() {
        const {
            datas, title, cancelName, confirmName, confirmClass
        } = this.props;
        return (
            <div
                data-name="__fixed_key_for_picker_modal__"
                className={s.layer}
                onClick={e => {
                    e.preventDefault();
                    e.stopPropagation();
                }}
            >
                <div className={s.header}>
                    <div className={cx(s.cancel, 'modal-close')} onClick={this.cancel}>
                        {cancelName}
                    </div>
                    <CSSTransitionGroup
                        className={s.titleTrans}
                        transitionName={{
                            enter: s.enter,
                            enterActive: s.enterActive,
                            leave: s.leave,
                            leaveActive: s.leaveActive,
                        }}
                        transitionEnter
                        transitionLeave
                        transitionEnterTimeout={400}
                        transitionLeaveTimeout={400}
                        component="div"
                    >
                        <div className={s.title} key={title}>
                            {title}
                        </div>
                    </CSSTransitionGroup>

                    <div className={cx(s.confirm, confirmClass)} onClick={this.submit}>
                        {confirmName}
                    </div>
                </div>

                <div className={s.pk}>{datas ? this.renderCommonUI() : this.renderDateUI()}</div>
            </div>
        );
    }
}
